Aplicacion de algoritmos de segmentacion y cluster en imagenes agricolas, mediante el uso de herramientas de computo ΒΆ
MODULO 3: HISTOGRAMAS
AUTOR: LOPEZ ESTEBAN MIGUEL
FECHA: 11 DE JULIO DEL 2024
IndiceΒΆ
- Calculo de Histogramas
1.1. Histogramas de imagenes en escala de grises
1.2. Histogramas de los canales RGB en imagenes
1.2.1. Canal rojo
1.2.2. Canal verde
1.2.3. Canal azul
1.2.4. Comparacion - Ecualizacion de histogramas
2.1. Ecualizacion de histogramas en imagenes en escala de grises
2.2. Ecualizacion de histogramas en imagenes a color
2.2.1. Ecualizacion de histogramas por canales en imagenes a color
2.2.2. Ecualizacion de histogramas en imagenes a color utilizando espacios de color
2.2.2.1. Ecualizacion de histogramas en el espacio de color YUV
2.2.2.2. Ecualizacion de histogramas en el espacio de color LAB
2.2.2.3. Ecualizacion de histogramas en el espacio de color HSV - Homologacion de histogramas
3.1. Lectura. carga y tratamiento previo de la imagen
3.2. Calcular los histogramas
3.3. Calcular la funcion de distribucion acumulativa (CDF)
3.4. Crear una tabla de mapeo de intensidades
3.5. aplicar la tabla de mapeo a la imagen
3.6. Visualizar los resultados - Referencias
Calculo de histogramasΒΆ
cv2.calcHist(). Esta funcion recibe varios parΓ‘metros que explicaremos a continuaciΓ³n: - ImΓ‘genes: puede ser una sola imagen o una lista de imΓ‘genes, las cuales deben ir entre corchetes, aunque sea solo una.
- Canales: en este se coloca el Γndice del canal del que se calcularΓ‘ el histograma, cada Γndice deberΓ‘ ir entre corchetes, en caso de trabajar una imagen con un solo canal, como por ejemplo una imagen en escala de grises se usarΓ‘ el Γndice
0. Por otro lado, si se trabaja con una imagen que tenga varios canales, se debe colocar el o los nΓΊmeros de los canales a usar, recordar que para contar los canales comenzamos con elcanal 0toda imagen comienza sus canales en este, y recordar que deben ir entre corchetes cada canal. - Mascara: mascara de imagen opcional para especificar una regiΓ³n de la imagen en la que se calculara el histograma. Si no se usa mascara se pasa el siguiente parametro
None. - Histsize: esta es la lista que especifica el nΓΊmero de contenedores (bins) en el histograma. Cada bin representa un rango de valores de intensidad de pixeles. Este parΓ‘metro tambiΓ©n debe ir entre corchetes.
- Rango: lista que especifica el rango de valores a considerar en el histograma. Cada rango debe estar entre corchetes.
A continuaciΓ³n, se muestra cΓ³mo usar esta funciΓ³n en diferentes imΓ‘genes.
Histograma de imΓ‘genes en escala de grises ΒΆ
#cargamos las librerias a ocupar en este modulo
import cv2
import matplotlib.pyplot as plt
import numpy as np
#cargamos la imagen a usar, en est caso "fcolores.jpg"
imagen = cv2.imread('fcolores.jpg')
#pasamos la imagen de bgr a rgb
imagen_rgb = cv2.cvtColor(imagen,cv2.COLOR_BGR2RGB)
#mostramos la imagen
plt.imshow(imagen_rgb)
plt.title('Imagen RGB')
plt.show()
#convetimos la imagen e escala de grises
imagen_gray = cv2.cvtColor(imagen_rgb,cv2.COLOR_BGR2GRAY)
#mostramos la imagen en escala de grises
plt.imshow(imagen_gray,cmap='gray')
plt.title('Imagen en escala de grises')
plt.show()
#calculamos el histogrma de la imagen
histogramagray1 = cv2.calcHist([imagen_gray],[0],None,[256],[0,256])
#mostramos el histograma
#definimos que vamos a mostrar y con que tipo de lineas y tamaΓ±o
plt.plot(histogramagray1,color='gray',linestyle='-',linewidth=2)
#agregamos un titulo y leyenda a los ejes
plt.title('Histograma de la imagen en escala de grises')
plt.xlabel('Intensidad')
plt.ylabel('Numero de pixeles')
#rellenamos el area debajo de nuestra grafica
plt.fill_between(range(256),histogramagray1[:,0],color='gray',alpha=0.5)
#definimos los rangos en los que trabaja nuestro grafico
plt.xlim([0,256])
plt.ylim([0,7000])
#activamos la cuadricula
plt.grid(True)
#mostramos nuestro histograma
plt.show()
Histogramas de los canales RGB en imΓ‘genes ΒΆ
cv2.calcHist() para mΓΊltiples canales, para esto retomaremos la imagen que ya cargamos en el tema anterior y mostraremos el histograma para cada canal de esta.
Canal rojoΒΆ
#histograma para canal rojo [0]
histograma_canal_r = cv2.calcHist([imagen_rgb],[0],None,[256],[0,256])
#mostramos el histograma
#definimos que vamos a mostrar y con que tipo de lineas y tamaΓ±o
plt.plot(histograma_canal_r,color='red',linestyle='-',linewidth=2)
#agregamos un titulo y leyenda a los ejes
plt.title('Histograma del canal rojo')
plt.xlabel('Intensidad')
plt.ylabel('Numero de pixeles')
#rellenamos el area debajo de nuestra grafica
plt.fill_between(range(256),histograma_canal_r[:,0],color='red',alpha=0.5)
#definimos los rangos en los que trabaja nuestro grafico
plt.xlim([0,256])
plt.ylim([0,40000])
#activamos la cuadricula
plt.grid(True)
#mostramos nuestro histograma
plt.show()
Canal verdeΒΆ
#histograma para canal verde [1]
histograma_canal_g = cv2.calcHist([imagen_rgb],[1],None,[256],[0,256])
#mostramos el histograma
#definimos que vamos a mostrar y con que tipo de lineas y tamaΓ±o
plt.plot(histograma_canal_g,color='green',linestyle='-',linewidth=2)
#agregamos un titulo y leyenda a los ejes
plt.title('Histograma del canal verde')
plt.xlabel('Intensidad')
plt.ylabel('Numero de pixeles')
#rellenamos el area debajo de nuestra grafica
plt.fill_between(range(256),histograma_canal_g[:,0],color='green',alpha=0.5)
#definimos los rangos en los que trabaja nuestro grafico
plt.xlim([0,256])
plt.ylim([0,15000])
#activamos la cuadricula
plt.grid(True)
#mostramos nuestro histograma
plt.show()
Canal azulΒΆ
#histograma para canal azul [2]
histograma_canal_b = cv2.calcHist([imagen_rgb],[2],None,[256],[0,256])
#mostramos el histograma
#definimos que vamos a mostrar y con que tipo de lineas y tamaΓ±o
plt.plot(histograma_canal_b,color='blue',linestyle='-',linewidth=2)
#agregamos un titulo y leyenda a los ejes
plt.title('Histograma del canal azul')
plt.xlabel('Intensidad')
plt.ylabel('Numero de pixeles')
#rellenamos el area debajo de nuestra grafica
plt.fill_between(range(256),histograma_canal_b[:,0],color='blue',alpha=0.5)
#definimos los rangos en los que trabaja nuestro grafico
plt.xlim([0,256])
plt.ylim([0,50000])
#activamos la cuadricula
plt.grid(True)
#mostramos nuestro histograma
plt.show()
ComparacionΒΆ
EcualizaciΓ³n de histogramas ΒΆ
Las imΓ‘genes con un histograma concentrado en un rango estrecho de valores de intensidad tienden a tener bajo contraste, lo que resulta en que los detalles de las Γ‘reas claras y obscuras sean difΓciles de distinguir.
La ecualizaciΓ³n ajusta la distribuciΓ³n de los valores de intensidad para utilizar rangos disponibles de manera mΓ‘s uniforme, esto se logra a travΓ©s de una transformaciΓ³n de los valores de intensidad que βesparceβ los valores mas frecuentes y βcompactaβ los menos frecuentes, resultando en un histograma mΓ‘s plano.
Esta tΓ©cnica es muy ΓΊtil en varios casos, sin embargo, muchas veces esta puede llegar a introducir artefactos no deseados en la imagen.Para ilustrar esta tΓ©cnica mostraremos como llevarla acabo en diferentes tipos de imΓ‘genes.
EcualizaciΓ³n de histogramas de imΓ‘genes en escala de grises ΒΆ
cv2.equalizeHist() de OpenCV, para ilustrar el procedimiento usaremos la imagen que convertimos en escala de grises.
#ecualizamos la imagen en escala de grises
imagen_ecualizada_gray = cv2.equalizeHist(imagen_gray)
#mostramos la imagen ecualizada y la imagen en escala de grises.
fig, axis = plt.subplots(1,2,figsize=(10,5))
#mostramos la imagen sin ecualizar
axis[0].imshow(imagen_gray,cmap='gray')
axis[0].set_title('Imagen sin ecualizar')
axis[0].axis('off')
#imagen ecualizada
axis[1].imshow(imagen_ecualizada_gray,cmap='gray')
plt.title('Imagen ecualizada')
axis[1].axis('off')
plt.suptitle('Diferencias entre imagen sin ecualizar e imagen ecualizada',fontsize=20)
plt.tight_layout()
plt.show()
#Calculamos el histograma de la imagen ecualizada
histogramagray_equalizado = cv2.calcHist([imagen_ecualizada_gray],[0],None,[256],[0,256])
fig,axis = plt.subplots(2,1,figsize=(20,25))
#mostramos el histograma sin ecualizar
axis[0].plot(histogramagray1,color='gray',linestyle='-',linewidth=2)
axis[0].set_title('Histograma sin escualizar',fontsize=30)
axis[0].set_xlabel('Intensidad',fontsize=30)
axis[0].set_ylabel('Numero de pixeles',fontsize=30)
axis[0].fill_between(range(256),histogramagray1[:,0],color='gray',alpha=0.5)
axis[0].set_xlim([0,256])
axis[0].set_ylim([0,7000])
axis[0].grid(True)
#mostramos el histograma de la imagen ecualizada
axis[1].plot(histogramagray_equalizado,color='gray',linestyle='-',linewidth=2)
axis[1].set_title('Histograma ecualizado',fontsize=30)
axis[1].set_xlabel('Intensidad',fontsize=30)
axis[1].set_ylabel('Numero de pixeles',fontsize=30)
axis[1].fill_between(range(256),histogramagray_equalizado[:,0],color='gray',alpha=0.5)
axis[1].set_xlim([0,256])
axis[1].set_ylim([0,7000])
axis[1].grid(True)
plt.tight_layout()
plt.show()
EcualizaciΓ³n de histogramas en imΓ‘genes a color ΒΆ
EcualizaciΓ³n de histogramas por canales en imΓ‘genes a colorΒΆ
#mostramos la imagen con la que vamos a trabajar
plt.imshow(imagen_rgb)
plt.title('Imagen a color')
plt.show()
#separamos la imagen en canales
r,g,b = cv2.split(imagen_rgb)
Canal rojo ΒΆ
#canal rojo
#ecualizamos el canal rojo
r_eq = cv2.equalizeHist(r)
#mostramos el canal normal y el ecualizado
fig, axis = plt.subplots(1,2,figsize=(10,5))
axis[0].imshow(r,cmap='gray')
axis[0].set_title('Canal rojo normal')
axis[0].axis('off')
axis[1].imshow(r_eq,cmap='gray')
axis[1].set_title('Canal rojo ecualizado')
axis[1].axis('off')
plt.tight_layout()
plt.show()
#calculamos el histograma del canal rojo ecualizado
histograma_canal_r_eq = cv2.calcHist([r_eq],[0],None,[256],[0,256])
#mostramos los histogramas
fig,axis = plt.subplots(2,1,figsize=(20,25))
#mostramos el histograma del canal rojo sin ecualizar
axis[0].plot(histograma_canal_r,color='red',linestyle='-',linewidth=2)
axis[0].set_title('Histograma del canal rojo sin escualizar',fontsize=30)
axis[0].set_xlabel('Intensidad',fontsize=30)
axis[0].set_ylabel('Numero de pixeles',fontsize=30)
axis[0].fill_between(range(256),histograma_canal_r[:,0],color='red',alpha=0.5)
axis[0].set_xlim([0,256])
axis[0].set_ylim([0,7000])
axis[0].grid(True)
#mostramos el histograma del canal rojo ecualizado
axis[1].plot(histograma_canal_r_eq,color='red',linestyle='-',linewidth=2)
axis[1].set_title('Histograma del canal rojo ecualizado',fontsize=30)
axis[1].set_xlabel('Intensidad',fontsize=30)
axis[1].set_ylabel('Numero de pixeles',fontsize=30)
axis[1].fill_between(range(256),histograma_canal_r_eq[:,0],color='red',alpha=0.5)
axis[1].set_xlim([0,256])
axis[1].set_ylim([0,7000])
axis[1].grid(True)
plt.tight_layout()
plt.show()
Canal verdeΒΆ
#canal verde
#ecualizamos el canal verde
g_eq = cv2.equalizeHist(g)
#mostramos el canal normal y el ecualizado
fig, axis = plt.subplots(1,2,figsize=(10,5))
axis[0].imshow(g,cmap='gray')
axis[0].set_title('Canal verde normal')
axis[0].axis('off')
axis[1].imshow(g_eq,cmap='gray')
axis[1].set_title('Canal verde ecualizado')
axis[1].axis('off')
plt.tight_layout()
plt.show()
#calculamos el histograma del canal verde ecualizado
histograma_canal_g_eq = cv2.calcHist([g_eq],[0],None,[256],[0,256])
#mostramos los histogramas
fig,axis = plt.subplots(2,1,figsize=(20,25))
#mostramos el histograma del canal verde sin ecualizar
axis[0].plot(histograma_canal_g,color='green',linestyle='-',linewidth=2)
axis[0].set_title('Histograma del canal verde sin escualizar',fontsize=30)
axis[0].set_xlabel('Intensidad',fontsize=30)
axis[0].set_ylabel('Numero de pixeles',fontsize=30)
axis[0].fill_between(range(256),histograma_canal_g[:,0],color='green',alpha=0.5)
axis[0].set_xlim([0,256])
axis[0].set_ylim([0,14000])
axis[0].grid(True)
#mostramos el histograma del canal verde ecualizado
axis[1].plot(histograma_canal_g_eq,color='green',linestyle='-',linewidth=2)
axis[1].set_title('Histograma del canal verde ecualizado',fontsize=30)
axis[1].set_xlabel('Intensidad',fontsize=30)
axis[1].set_ylabel('Numero de pixeles',fontsize=30)
axis[1].fill_between(range(256),histograma_canal_g_eq[:,0],color='green',alpha=0.5)
axis[1].set_xlim([0,256])
axis[1].set_ylim([0,14000])
axis[1].grid(True)
plt.tight_layout()
plt.show()
Canal azulΒΆ
#canal aul
#ecualizamos el canal azul
b_eq = cv2.equalizeHist(b)
#mostramos el canal normal y el ecualizado
fig, axis = plt.subplots(1,2,figsize=(10,5))
axis[0].imshow(b,cmap='gray')
axis[0].set_title('Canal azul normal')
axis[0].axis('off')
axis[1].imshow(b_eq,cmap='gray')
axis[1].set_title('Canal azul ecualizado')
axis[1].axis('off')
plt.tight_layout()
plt.show()
#calculamos el histograma del canal azul ecualizado
histograma_canal_b_eq = cv2.calcHist([b_eq],[0],None,[256],[0,256])
#mostramos los histogramas
fig,axis = plt.subplots(2,1,figsize=(20,25))
#mostramos el histograma del canal azul sin ecualizar
axis[0].plot(histograma_canal_b,color='blue',linestyle='-',linewidth=2)
axis[0].set_title('Histograma del canal azul sin escualizar',fontsize=30)
axis[0].set_xlabel('Intensidad',fontsize=30)
axis[0].set_ylabel('Numero de pixeles',fontsize=30)
axis[0].fill_between(range(256),histograma_canal_b[:,0],color='blue',alpha=0.5)
axis[0].set_xlim([0,256])
axis[0].set_ylim([0,14000])
axis[0].grid(True)
#mostramos el histograma del canal azul ecualizado
axis[1].plot(histograma_canal_b_eq,color='blue',linestyle='-',linewidth=2)
axis[1].set_title('Histograma del canal azul ecualizado',fontsize=30)
axis[1].set_xlabel('Intensidad',fontsize=30)
axis[1].set_ylabel('Numero de pixeles',fontsize=30)
axis[1].fill_between(range(256),histograma_canal_b_eq[:,0],color='blue',alpha=0.5)
axis[1].set_xlim([0,256])
axis[1].set_ylim([0,14000])
axis[1].grid(True)
plt.tight_layout()
plt.show()
Union de canalesΒΆ
#unimso los canales equalizados
imagen_rgb_eq = cv2.merge([r_eq,g_eq,b_eq])
#mostramos la imagen original y la imagen equalizada
fig,axis = plt.subplots(1,2,figsize=(10,5))
axis[0].imshow(imagen_rgb)
axis[0].set_title('Imagen original')
axis[0].axis('off')
axis[1].imshow(imagen_rgb_eq)
axis[1].set_title('Imagen equalizada')
axis[1].axis('off')
plt.tight_layout()
plt.show()
EcualizaciΓ³n de histogramas en imΓ‘genes a color utilizando espacios de color ΒΆ
EcualizaciΓ³n de histogramas en el espacio de color YUVΒΆ
#convertimos nuestra imagen a espacio YUV
imagen_yuv =cv2.cvtColor(imagen_rgb,cv2.COLOR_RGB2YUV)
#mostramos la imagen
plt.imshow(imagen_yuv)
plt.title('Imagen en espacio YUV')
plt.axis('off')
plt.show()
#ecualizamos solo el canal Y
luminancia_eq = cv2.equalizeHist(imagen_yuv[:,:,0])
#calculamos los histogramas
#sin ecualizar
histograma_luminancia = cv2.calcHist([imagen_yuv[:,:,0]],[0],None,[256],[0,256])
#ecualizado
histograma_luminancia_eq = cv2.calcHist([luminancia_eq],[0],None,[256],[0,256])
#mostramos los histogramas
fig,axis = plt.subplots(2,1,figsize=(20,25))
#mostramos el histograma del canal y sin ecualizar
axis[0].plot(histograma_luminancia,color='gray',linestyle='-',linewidth=2)
axis[0].set_title('Histograma del canal Y sin escualizar',fontsize=30)
axis[0].set_xlabel('Intensidad',fontsize=30)
axis[0].set_ylabel('Numero de pixeles',fontsize=30)
axis[0].fill_between(range(256),histograma_luminancia[:,0],color='gray',alpha=0.5)
axis[0].set_xlim([0,256])
axis[0].set_ylim([0,8000])
axis[0].grid(True)
#mostramos el histograma del canal y ecualizado
axis[1].plot(histograma_luminancia_eq,color='gray',linestyle='-',linewidth=2)
axis[1].set_title('Histograma del canal y ecualizado',fontsize=30)
axis[1].set_xlabel('Intensidad',fontsize=30)
axis[1].set_ylabel('Numero de pixeles',fontsize=30)
axis[1].fill_between(range(256),histograma_luminancia_eq[:,0],color='gray',alpha=0.5)
axis[1].set_xlim([0,256])
axis[1].set_ylim([0,8000])
axis[1].grid(True)
plt.tight_layout()
plt.show()
#modificamos la imagen con la nueva ecualizacion
imagen_yuv[:,:,0] = luminancia_eq
#convertimos la imagen de nuevo en RGB
imagen_ecualizada_y = cv2.cvtColor(imagen_yuv,cv2.COLOR_YUV2RGB)
#mostramos la imagen modificada
fig, axis = plt.subplots(1,2,figsize=(10,5))
axis[0].imshow(imagen_rgb)
axis[0].set_title('Imagen original')
axis[0].axis('off')
axis[1].imshow(imagen_ecualizada_y)
axis[1].set_title('Imagen ecualizada')
axis[1].axis('off')
plt.tight_layout()
plt.show()
EcualizaciΓ³n de histogramas en el espacio de color LAB ΒΆ
#convertimos la imagen a espacio LAB
imagen_lab = cv2.cvtColor(imagen_rgb,cv2.COLOR_RGB2LAB)
#ecualizamos el canal L
imagen_lab_l_eq = cv2.equalizeHist(imagen_lab[:,:,0])
#calculamos el histograma antes y despues de ecualizar
#antes de ecualizar
histograma_lab_l = cv2.calcHist([imagen_lab[:,:,0]],[0],None,[256],[0,256])
#despues de ecualizar
histograma_lab_l_eq = cv2.calcHist([imagen_lab_l_eq],[0],None,[256],[0,256])
#mostrammos los histogramas
fig,axis = plt.subplots(2,1,figsize=(20,25))
#mostramos el histograma del canal L sin ecualizar
axis[0].plot(histograma_lab_l,color='gray',linestyle='-',linewidth=2)
axis[0].set_title('Histograma del canal L sin escualizar',fontsize=30)
axis[0].set_xlabel('Intensidad',fontsize=30)
axis[0].set_ylabel('Numero de pixeles',fontsize=30)
axis[0].fill_between(range(256),histograma_lab_l[:,0],color='gray',alpha=0.5)
axis[0].set_xlim([0,256])
axis[0].set_ylim([0,8000])
axis[0].grid(True)
#mostramos el histograma del canal L ecualizado
axis[1].plot(histograma_lab_l_eq,color='gray',linestyle='-',linewidth=2)
axis[1].set_title('Histograma del canal L ecualizado',fontsize=30)
axis[1].set_xlabel('Intensidad',fontsize=30)
axis[1].set_ylabel('Numero de pixeles',fontsize=30)
axis[1].fill_between(range(256),histograma_lab_l_eq[:,0],color='gray',alpha=0.5)
axis[1].set_xlim([0,256])
axis[1].set_ylim([0,8000])
axis[1].grid(True)
plt.tight_layout()
plt.show()
#modificamos la imagen con la nueva ecualizacion
imagen_lab[:,:,0] = imagen_lab_l_eq
#convertimos la imagen de nuevo en RGB
imagen_lab_eq = cv2.cvtColor(imagen_lab,cv2.COLOR_Lab2RGB)
#mostramos la imagen modificada
fig, axis = plt.subplots(1,2,figsize=(10,5))
axis[0].imshow(imagen_rgb)
axis[0].set_title('Imagen original')
axis[0].axis('off')
axis[1].imshow(imagen_lab_eq)
axis[1].set_title('Imagen ecualizada')
axis[1].axis('off')
plt.tight_layout()
plt.show()
EcualizaciΓ³n de histogramas en el espacio de color HSVΒΆ
#convertimos la imagen de RGB a HSV
imagen_hsv = cv2.cvtColor(imagen_rgb,cv2.COLOR_RGB2HSV)
#ecualizamos el canal V
#el canal v es el 2
imagen_hsv_v_eq = cv2.equalizeHist(imagen_hsv[:,:,2])
#calculamos el histograma antes y despues de ecualizar
#antes de ecualizar
histograma_hsv = cv2.calcHist([imagen_hsv[:,:,2]],[0],None,[256],[0,256])
#despues de ecualizar
histograma_hsv_eq = cv2.calcHist([imagen_hsv_v_eq],[0],None,[256],[0,256])
#mostrammos los histogramas
fig,axis = plt.subplots(2,1,figsize=(20,25))
#mostramos el histograma del canal V sin ecualizar
axis[0].plot(histograma_hsv,color='gray',linestyle='-',linewidth=2)
axis[0].set_title('Histograma del canal V sin escualizar',fontsize=30)
axis[0].set_xlabel('Intensidad',fontsize=30)
axis[0].set_ylabel('Numero de pixeles',fontsize=30)
axis[0].fill_between(range(256),histograma_hsv[:,0],color='gray',alpha=0.5)
axis[0].set_xlim([0,256])
axis[0].set_ylim([0,8000])
axis[0].grid(True)
#mostramos el histograma del canal V ecualizado
axis[1].plot(histograma_hsv_eq,color='gray',linestyle='-',linewidth=2)
axis[1].set_title('Histograma del canal V ecualizado',fontsize=30)
axis[1].set_xlabel('Intensidad',fontsize=30)
axis[1].set_ylabel('Numero de pixeles',fontsize=30)
axis[1].fill_between(range(256),histograma_hsv_eq[:,0],color='gray',alpha=0.5)
axis[1].set_xlim([0,256])
axis[1].set_ylim([0,8000])
axis[1].grid(True)
plt.tight_layout()
plt.show()
#modificamos la imagen con la nueva ecualizacion
imagen_hsv[:,:,2] = imagen_hsv_v_eq
#convertimos la imagen de nuevo en RGB
imagen_hsv_eq = cv2.cvtColor(imagen_hsv,cv2.COLOR_HSV2RGB)
#mostramos la imagen modificada
fig, axis = plt.subplots(1,2,figsize=(10,5))
axis[0].imshow(imagen_rgb)
axis[0].set_title('Imagen original')
axis[0].axis('off')
axis[1].imshow(imagen_hsv_eq)
axis[1].set_title('Imagen ecualizada')
axis[1].axis('off')
plt.tight_layout()
plt.show()
HomologaciΓ³n de histogramas ΒΆ
Las imΓ‘genes capturadas en diferentes condiciones de iluminaciΓ³n o con diferentes dispositivos pueden tener distribuciones de intensidad diferentes, lo que dificulta la comparaciΓ³n o combinaciΓ³n de estas imΓ‘genes. La homologaciΓ³n ajusta las intensidades de una imagen (imagen de origen) para que su histograma coincida con el histograma de otra imagen (imagen de referencia).
Sin embrago este mΓ©todo trae consigo algunas desventajas y es que algunas veces puede llegar a introducir objetos no deseados en las imΓ‘genes, ademΓ‘s de que los resultados dependen en gran medida de la imagen de referencia, por lo cual una referencia inadecuada puede llevar a una homologaciΓ³n pobre.
Para llevar a cabo esta tΓ©cnica se siguen los siguientes pasos:
- Lectura, carga de imΓ‘genes y tratamiento previo
- Calcular los histogramas
- Calcular la funciΓ³n de distribuciΓ³n acumulativa (CDF)
- Crear una tabla de mapeo de intensidades
- Aplicar la tabla de mapeo a la imagen de origen
- Visualizar los resultados.
Estos pasos se explican de manera as detallada a continuaciΓ³n.
Lectura, carga y tratamiento previo de la imagen ΒΆ
#cargamos la imagenes con las que trabajaremos
#imagen de origen
imagen_origen = cv2.imread('imagen_origen.jpg')
imagen_origen_rgb = cv2.cvtColor(imagen_origen,cv2.COLOR_BGR2RGB)
#cargamos la imagen de refrencia
imagen_referencia = cv2.imread('imagen_referencia.jpg')
imagen_referencia_rgb = cv2.cvtColor(imagen_referencia,cv2.COLOR_BGR2RGB)
#mostramos las imagenes
fig,axis = plt.subplots(1,2,figsize=(10,5))
axis[0].imshow(imagen_origen_rgb)
axis[0].set_title('Imagen de origen')
axis[1].imshow(imagen_referencia_rgb)
axis[1].set_title('Imagen de referencia')
plt.tight_layout()
plt.show()
#convertimos la imagen es espacio de color YUV, se puede trabajar en otros espacios
#imagen origen
imagen_origen_YUV = cv2.cvtColor(imagen_origen_rgb,cv2.COLOR_RGB2YUV)
#imagen de referencia
imagen_refrencia_yuv = cv2.cvtColor(imagen_referencia_rgb,cv2.COLOR_RGB2YUV)
Calcular los histogramas ΒΆ
#calculamos los histogramas
#imagen de origen
histograma_origen = cv2.calcHist([imagen_origen_YUV[:,:,0]],[0],None,[256],[0,256])
#imagen de referencia
histograma_referencia = cv2.calcHist([imagen_refrencia_yuv[:,:,0]],[0],None,[256],[0,256])
#mostramos luna comparacion entre los histogramas
fig,axis = plt.subplots(2,1,figsize=(20,25))
#mostramos el histograma del canal V sin ecualizar
axis[0].plot(histograma_origen,color='black',linestyle='-',linewidth=2)
axis[0].set_title('Histograma del canal Y sin escualizar',fontsize=30)
axis[0].set_xlabel('Intensidad',fontsize=30)
axis[0].set_ylabel('Numero de pixeles',fontsize=30)
axis[0].fill_between(range(256),histograma_origen[:,0],color='gray',alpha=0.5)
axis[0].set_xlim([0,256])
axis[0].set_ylim([0,8000])
axis[0].grid(True)
#mostramos el histograma del canal y ecualizado
axis[1].plot(histograma_referencia,color='black',linestyle='-',linewidth=2)
axis[1].set_title('Histograma del canal y ecualizado',fontsize=30)
axis[1].set_xlabel('Intensidad',fontsize=30)
axis[1].set_ylabel('Numero de pixeles',fontsize=30)
axis[1].fill_between(range(256),histograma_referencia[:,0],color='gray',alpha=0.5)
axis[1].set_xlim([0,256])
axis[1].set_ylim([0,8000])
axis[1].grid(True)
plt.tight_layout()
plt.show()
Calcular la funciΓ³n de distribuciΓ³n acumulativa (CDF) ΒΆ
#calculamos el CDF
#cdf imagen de origen
cdf_origen = histograma_origen.cumsum()
#cdf imagen referencia
cdf_referencia = histograma_referencia.cumsum()
#calculamos el cdf normalizado
#cdf origen
cdf_normalizado_origen = cdf_origen * histograma_origen.max() / cdf_origen.max()
#cdf referencias
cdf_normalizado_referencia = cdf_referencia * histograma_referencia.max() / cdf_referencia.max()
Crear una tabla de mapeo de intensidadesΒΆ
#creamos una tabla de mapeo de intensidades
mapa = np.zeros(256,dtype=np.uint8)
for i in range(256):
diff = np.abs(cdf_normalizado_origen[i] - cdf_normalizado_referencia)
mapa[i] = np.argmin(diff)
Aplicar la tabla de mapeo a la imagen de origenΒΆ
#aplicamos la tabla de mapeo a la imagen de origen
imagen_origen_YUV[:,:,0] =cv2.LUT(imagen_origen_YUV[:,:,0],mapa)
Visualizar los resultados ΒΆ
#convertimos la imagen en rgb
imagen_homologada = cv2.cvtColor(imagen_origen_YUV,cv2.COLOR_YUV2RGB)
#mostramos la comparacion entre las imagenes
fig,axis = plt.subplots(1,3,figsize=(15,5))
axis[0].imshow(imagen_origen_rgb)
axis[0].set_title('Imagen de origen')
axis[0].axis('off')
axis[1].imshow(imagen_referencia_rgb)
axis[1].set_title('Imagen de referencia')
axis[1].axis('off')
axis[2].imshow(imagen_homologada)
axis[2].set_title('Imagen homologada')
axis[2].axis('off')
plt.tight_layout()
plt.show()